<?php

class Model_AclManager
{

    function Model_AclManager()
    {
    }

    /**
     * 获取指定用户，及其整理后的权限信息
     * @param mixed $conditions
     */
    function getUserWithPermissions($conditions)
    {
		$tb_Members =& FLEA::getSingleton('Table_Members');
		/* @var $tb_Members Table_Members */
		
    	// 获得指定用户
    	$tb_Members->disableLink('user_group');
		$user = $tb_Members->find($conditions);
		if( empty($user) ){ return false; }
		
		// 获得用户所在组的权限继承路径
		$ugPath = $this->getugPath($user['user_group_id']);
		
		// 获得路径用户组的全部权限信息
		$usergroups = $this->getugPermissions($ugPath);
				
		// 获得继承状态数组（合并了用户和用户组权限信息）
		$usergroups[] = $user;
		$inherited = $this->getInheritArr($usergroups);
		
		// 整理最终的角色信息
		$haveRoles = $this->userHaveRoles($inherited);
		
		// 合并到user数组中
		unset($user['permissions']);
		$user['roles'] = $haveRoles;
		
		return $user;
		
    }
    
	/**
	 * 获取一个用户及继承权限及所有关联数据
	 * @param mixed $conditions
	 * @return array
	 */
	function loadUser($conditions){
		$tb_Members =& FLEA::getSingleton('Table_Members');
		/* @var $tb_Members Table_Members */
		
    	// 获得指定用户
    	$tb_Members->disableLink('user_group');
		$user = $tb_Members->find($conditions);
		if( empty($user) ){ return false; }
		
		// 获得用户所在组的权限继承路径
		$ugPath = $this->getugPath($user['user_group_id']);
		
		// 获得路径用户组的全部继承权限信息
		$usergroups = $this->getInheritArr($this->getugPermissions($ugPath));
		
		// 合并到用户数组中去
		$user['allow'] = $usergroups['allow'];
		$user['deny'] = $usergroups['deny'];
		
		return $user;
		
	}
    
	/**
	 * 检查用户登录数据
	 * @param array $user
	 * @return boolin
	 */
	function checkUser($user){
		$tb_Member =& FLEA::getSingleton('Table_Members');
		/*@var $tb_Member Table_Members*/
		if($tb_Member->validateUser($user['username'],$user['password'])){
			return true;
		}else{
			return false;
		}
	}
    
    /**
     * 获得指定用户组及其继承权限信息
     * @param mixed $conditions
     */
    function getUgInherit($conditions){
    	
    	$tb_UserGroups =& FLEA::getSingleton('Table_UserGroups');
    	/* @var $tb_UserGroups Table_UserGroups */
    	
    	// 获取指定用户组
    	$tb_UserGroups->disableLink('Members');
    	$userGroup = $tb_UserGroups->find($conditions);
    	
    	// 获得用户组权限继承路径
    	$ugPath = $this->getugPath($userGroup['parent_id']);
    	
    	// 获得继承的权限信息
    	$inherited = $this->getInheritArr($this->getugPermissions($ugPath));
    	
    	// 合并
    	// unset($userGroup['permissions'],$userGroup['roles']);
    	$userGroup['allow'] = $inherited['allow'];
    	$userGroup['deny'] = $inherited['deny'];
    	
    	return $userGroup;
    	
    }
    
    /**
     * 返回最终的用户Roles数组
     * @param array $inherited
     * @return array $roles
     */
    function userHaveRoles($inherited){
    	$roles = array();
    	
    	// 就是合并roles和permissions，并且为deny的加上deny_前缀
    	foreach ($inherited as $key=>$value) {
    		if($key=='allow'){
    			foreach ($value['roles'] as $onerole) {
    				$roles[] = $onerole;
    			}
    			foreach ($value['permissions'] as $onerole) {
    				$roles[] = $onerole;;
    			}
    		}else{
    		    foreach ($value['roles'] as $onerole) {
    				$roles[] = 'deny_' . $onerole;
    			}
    			foreach ($value['permissions'] as $onerole) {
    				$roles[] = 'deny_' . $onerole;;
    			}
    		}
    	}
    	return $roles;
    }
    
    
    /**
     * 根据用户组权限继承路径数组返回整理后的权限继承关系
     * @param array $usergroups
     */
	function getInheritArr($usergroups)
	{
		$arr = array(
				'allow'=>array(
					'roles'=>array(),
					'permissions'=>array()
				),
				'deny'=>array(
					'roles'=>array(),
					'permissions'=>array()
				)
			);
		foreach ($usergroups as $usergroup) {
			
			if(is_array($usergroup['roles'])){
				foreach ($usergroup['roles'] as $role) {
					if($role['join_is_include']==1){
						
						// 如果继承权限中没有绑定此角色
						if(!in_array($role['rolename'],$arr['allow']['roles'])){
							// 在绑定中添加此角色
							$arr['allow']['roles'][] = $role['rolename'];
							// 如果继承权限曾经拒绝了此角色
							if(in_array($role['rolename'],$arr['deny']['roles'])){
								// 则删除掉原来拒绝的角色，因为deny与allow是互斥的
								$unsetkey = array_search($role['rolename'],$arr['deny']['roles']);
								unset($arr['deny']['roles'][$unsetkey]);
							}
						}
						
					}else{
						// 如果继承权限中没有拒绝此角色
						if(!in_array($role['rolename'],$arr['deny']['roles'])){
							// 则拒绝此角色
							$arr['deny']['roles'][] = $role['rolename'];
							// 如果继承权限中曾经绑定此角色
							if(in_array($role['rolename'],$arr['allow']['roles'])){
								// 则删除掉原来绑定的角色，因为deny与allow是互斥的
								$unsetkey = array_search($role['rolename'],$arr['allow']['roles']);
								unset($arr['allow']['roles'][$unsetkey]);
							}
						}
					}
				}
			}
			if(is_array($usergroup['permissions'])){
				foreach ($usergroup['permissions'] as $permission) {
					if($permission['join_is_allow']==1){
						
						// 如果继承权限中没有绑定此权限
						if(!in_array($permission['pername'],$arr['allow']['permissions'])){
							// 添加
							$arr['allow']['permissions'][] = $permission['pername'];
							// 如果曾经拒绝过
							if(in_array($permission['pername'],$arr['deny']['permissions'])){
								// 删除
								$unsetkey = array_search($permission['pername'],$arr['deny']['permissions']);
								unset($arr['deny']['permissions'][$unsetkey]);
							}
						}
						
					}else{
						// 如果没有拒绝过
						if(!in_array($permission['pername'],$arr['deny']['permissions'])){
							// 添加
							$arr['deny']['permissions'][] = $permission['pername'];
							// 如果曾经绑定过
							if(in_array($permission['pername'],$arr['allow']['permissions'])){
								// 删除
								$unsetkey = array_search($permission['pername'],$arr['allow']['permissions']);
								unset($arr['allow']['permissions'][$unsetkey]);
							}
						}
					}
				}
			}
		}
		
		return $arr;
		
	}
    
    /**
     * 获得一组用户组的Role和Permission
     * @param @return array usergroups $ugList
     */
    function getugPermissions($ugList)
    {
    	$tb_UserGroups =& FLEA::getSingleton('Table_UserGroups');
    	/* @var $tb_UserGroups Table_UserGroups */
    	
    	// 关联信息中不包含用户信息
    	$tb_UserGroups->disableLink('members');
    	
    	foreach ($ugList as $key=>$value) {
    		$ugList[$key] = array();
    		$ugList[$key] = $tb_UserGroups->find($value);
    	}
    	return $ugList;
    	
    }
    
    /**
     * 返回指定的用户组的权限继承路径(由user_group_id组成的数组)
     * @param array $user_group_id
     */
    function getugPath($user_group_id)
    {
    	$tb_UserGroups =& FLEA::getSingleton('Table_UserGroups');
    	/* @var $tb_UserGroups Table_UserGroups */
    	
    	$usergroups = $tb_UserGroups->findAll();
    	$arr = $this->_getpath($usergroups, $user_group_id);
    	sort($arr);
    	return $arr;
    }
    
    /**
     * 递归获得一个树到达某节点的路径
     *
     * @param arraytree $arr
     * @param int $pathto
     * @param @return array $path
     */
    function _getpath($arr, $pathto, $path = array())
    {
    	foreach ($arr as $value) {
    		if($value['user_group_id']==$pathto){
    			$path[] = $value['user_group_id'];
    			if($value['parent_id']==0){
    				break;
    			}
    			$path = $this->_getpath($arr, $value['parent_id'], $path);
    		}
    	}
    	return $path;
    	
    }
    
    
    /**
     * 更新用户组绑定的权限，这里先删除了原有权限，再插入新的权限，
     * 以保证在绑定权限为空的情况下能清空绑定
     * @param array $usergroup 从表单获取的权限数据，需要整理后使用
     * @return boolin
     */
    function saveugBand($usergroup){
    	
    	//整理成能够接受的数据
    	$arr = array();
		$arr['user_group_id'] = $usergroup['user_group_id'];
		
		if(!empty($usergroup['roles'])){
			$i = 0;
			foreach ($usergroup['roles'] as $key=>$value) {
				$arr['roles'][$i]['role_id'] = $key;
				$arr['roles'][$i]['#JOIN#']['is_include'] = $usergroup['is_include'][$key];
				$i++;
			}
		}
		if(!empty($usergroup['permissions'])){
			$i = 0;
			foreach ($usergroup['permissions'] as $key=>$value) {
				$arr['permissions'][$i]['permission_id'] = $key;
				$arr['permissions'][$i]['#JOIN#']['is_allow'] = $usergroup['is_allow'][$key];
				$i++;
			}
		}
		
		$tb_UhasP =& FLEA::getSingleton('Table_UserGroupsHasPermissions');
		/*@var $tb_UhasP Table_UserGroupsHasPermissions*/
		$tb_UhasR =& FLEA::getSingleton('Table_UserGroupsHasRoles');
		/*@var $tb_UhasR Table_UserGroupsHasRoles*/
		
		// 删除与该用户组相关的记录
		$tb_UhasP->removeByConditions("user_group_id = '{$arr['user_group_id']}'");
		$tb_UhasR->removeByConditions("user_group_id = '{$arr['user_group_id']}'");
		
		$tb_ug =& FLEA::getSingleton('Table_UserGroups');
		/*@var $tb_ug Table_UserGroups*/
		
		// 插入关联记录
		if(empty($usergroup['permissions']) and empty($usergroup['roles'])){
			return false;
		}else{
			return $tb_ug->update($arr);
		}
		
    }

    /**
     * 更新用户绑定的权限
     * @param array $user
     * @return int
     */
    function saveuserBand($user){
        //整理成能够接受的数据
    	$arr = array();
		$arr['member_id'] = $user['member_id'];
		
		if(!empty($user['roles'])){
			$i = 0;
			foreach ($user['roles'] as $key=>$value) {
				$arr['roles'][$i]['role_id'] = $key;
				$arr['roles'][$i]['#JOIN#']['is_include'] = $user['is_include'][$key];
				$i++;
			}
		}
		if(!empty($user['permissions'])){
			$i = 0;
			foreach ($user['permissions'] as $key=>$value) {
				$arr['permissions'][$i]['permission_id'] = $key;
				$arr['permissions'][$i]['#JOIN#']['is_allow'] = $user['is_allow'][$key];
				$i++;
			}
		}
		
		$tb_UhasP =& FLEA::getSingleton('Table_MembersHasPermissions');
		/*@var $tb_UhasP Table_MemberHasPermissions*/
		$tb_UhasR =& FLEA::getSingleton('Table_MemberHasRoles');
		/*@var $tb_UhasR Table_MemberHasRoles*/
		
		// 删除与该用户组相关的记录
		$tb_UhasP->removeByConditions("member_id = '{$arr['member_id']}'");
		$tb_UhasR->removeByConditions("member_id = '{$arr['member_id']}'");
		
		$tb_user =& FLEA::getSingleton('Table_Members');
		/*@var $tb_ug Table_Members*/
		
		// 插入关联记录
		if(!empty($user['permissions']) or !empty($user['roles'])){
			$tb_user->update($arr);
		}
		
		return $arr['member_id'];
		
    }
    
    /**
     * 更新角色绑定的权限
     *
     * @param array $role
     * @return boolin
     */
    function saveroleBand($role){
    	// 还是先整理一下
    	$arr = array();
    	$arr['role_id'] = $role['role_id'];
    	
    	if(!empty($role['permissions'])){
    		$i = 0;
	    	foreach ($role['permissions'] as $key=>$value) {
	    		$arr['permissions'][$i]['permission_id'] = $key;
	    		$i++;
	    	}
    	}
    	$tb_Roles =& FLEA::getSingleton('Table_Roles');
    	/*@var $tb_Roles Table_Roles*/
    	return $tb_Roles->update($arr);
    }
    
    /**
     * 获取角色信息及其对应的权限
     * @param mixed $conditions
     * @param array $role
     */
    function loadRole($conditions){
    	
    	$tb_roles =& FLEA::getSingleton('Table_Roles');
    	/*@var $tb_roles Table_Roles*/
    	$tb_roles->disableLinks(array('members','usergroups'));
    	$role = $tb_roles->find($conditions);
    	
    	return $role;
    }
	
    /**
     * 重新生成ACT权限表
     */
    function rewriteACT(){
		$tb_pergroups =& FLEA::getSingleton('Table_PermissionGroups');
		/*@var $tb_pergroup Table_PermissionGroups*/
		$tb_permissions =& FLEA::getSingleton('Table_Permissions');
		/*@var $tb_permissions Table_Permissions*/
		
		$tb_pergroups->clearLinks();
		$tb_permissions->disableLink('permission_group');
		
		$perGroups = $tb_pergroups->findAll();
		
		foreach ($perGroups as $key=>$value){
			$perGroups[$key]['permissions'] = $tb_permissions->findAll("permission_group_id = '{$value['permission_group_id']}'");
		}
		
		
		// 整理成ACT表的格式
		$ACT = array();
		foreach ($perGroups as $oneGroup) {
			$controllername = str_replace('controller_','',$oneGroup['permission_group_name']);
			$ACT[$controllername] = array();
			
			// 如果need_login字段为1，也就是需要验证
			if($oneGroup['need_login']){
				foreach ($oneGroup['permissions'] as $onePer) {
					$actionname = str_replace($oneGroup['permission_group_name'].'_','',$onePer['pername']);
						
						$allow = 'admin,' . $onePer['pername'];
						$deny = 'deny_admin, deny_' . $onePer['pername'];
						if(is_array($onePer['roles'])){
							foreach ($onePer['roles'] as $oneRole) {
								$allow .= ','.$oneRole['rolename'];
								$deny .= ',deny_'.$oneRole['rolename'];
							}
						}
						$ACT[$controllername]['actions'][$actionname] = array('allow'=>$allow,'deny'=>$deny);
						
				}
			// 不需要验证的控制器	
			}else{
				$ACT[$controllername]['allow'] = RBAC_EVERYONE;
			}
			
		}
		
		$act_table = '<?php return ' . var_export($ACT,true) . '?>';
		file_put_contents(APPDIR.'/Config/ACT.sys.php', $act_table);
    }
    
    
    
}
